package com.redisson.controller;

import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RCountDownLatch;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @program: MultiProject
 * @description:
 * @author: liangshuai
 * @create: 2020-11-10 17:51
 **/
@RestController
@RequestMapping("lock")
@Slf4j
public class LockController {

    @Autowired
    private RedissonClient redissonClient;

    /**
     * localhost:8080/lock/t1/1
     * RCountDownLatch 测试
     *
     * @param time
     * @throws InterruptedException
     */
    @GetMapping("/t1/{time}")
    public void t1(@PathVariable String time) throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(2);
        final RCountDownLatch latch = redissonClient.getCountDownLatch("latch1");
        latch.trySetCount(5);
        executor.execute(new Runnable() {
            @Override
            public void run() {
                log.info("线程{}获取成功", Thread.currentThread().getName());
                latch.countDown();
                log.info("线程{}操作完成", Thread.currentThread().getName());
            }
        });
        executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    log.info("线程{}获取成功", Thread.currentThread().getName());
                    latch.await(550, TimeUnit.MILLISECONDS);
                    log.info("线程{}操作完成", Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        executor.shutdown();
        executor.awaitTermination(10, TimeUnit.SECONDS);
        log.info("执行完毕");
    }

    /**
     * localhost:8080/lock/t2/1
     * 公平锁实现
     * @throws InterruptedException
     */
    @GetMapping("/t2/{time}")
    public void t2() throws InterruptedException {
        RLock lock = redissonClient.getFairLock("test");
        int size = 10;
        List<Thread> threads = new ArrayList<Thread>();
        for (int i = 0; i < size; i++) {
            final int j = i;
            Thread t = new Thread() {
                @Override
                public void run() {
                    lock.lock();
                    lock.unlock();
                }
            };

            threads.add(t);
        }

        for (Thread thread : threads) {
            thread.start();
            thread.join(5);
        }

        for (Thread thread : threads) {
            thread.join();
        }
    }


    @GetMapping("/t3/{time}")
    public void t3() throws InterruptedException {
        RLock lock = redissonClient.getLock("lock");
        lock.lock(2, TimeUnit.SECONDS);

        Thread t = new Thread() {
            public void run() {
                RLock lock1 = redissonClient.getLock("lock");
                lock1.lock();
                lock1.unlock();
            };
        };

        t.start();
        t.join();

        redissonClient.shutdown();
    }


}
